package de.tu_darmstadt.gdi1.battleship.controller;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.util.Locale;
import java.util.jar.JarInputStream;

import javax.swing.JDialog;
import javax.swing.JOptionPane;

import acm.io.IODialog;

import de.tu_darmstadt.gdi1.battleship.exceptions.InternalFailureException;
import de.tu_darmstadt.gdi1.battleship.exceptions.InvalidLevelFileException;
import de.tu_darmstadt.gdi1.battleship.exceptions.ParameterOutOfRangeException;
import de.tu_darmstadt.gdi1.battleship.model.BattleshipGame;
import de.tu_darmstadt.gdi1.battleship.view.Skin;
import de.tu_darmstadt.gdi1.battleship.view.StudentWindow;

public class StudentWindowListener implements ActionListener, KeyListener {

	private BattleshipGame bsg;
	private StudentWindow mainWnd;
	private UserInteraction mainCtrl;

	public StudentWindowListener(BattleshipGame bsg, StudentWindow mainWnd,
			UserInteraction mainCtrl) {

		this.bsg = bsg;
		this.mainWnd = mainWnd;
		this.mainCtrl = mainCtrl;

	}

	/**
	 * Implements the functionality of the menu. An action follows a click.
	 */
	@Override
	public void actionPerformed(ActionEvent a) {

		// starts an already random created level
		if (a.getSource() == mainWnd.getMntmRanLoadLvl())
			mainCtrl.loadRandomStandardLevel();

		// creates random level and starts it
		else if (a.getSource() == mainWnd.getMntmRanNewLvl())
			mainCtrl.generateRandomLevel();

		// creates level, where the player places his ships. the cpu ships are
		// randomly generated
		else if (a.getSource() == mainWnd.getMntmSelfMade())
			mainCtrl.placeShips();

		// Loads a skin out of a folder.
		else if (a.getSource() == mainWnd.getMntmLoadSkin())
			mainCtrl.loadSkinFromFolder();

		// loads a level out of a folder.
		else if (a.getSource() == mainWnd.getMntmLoadLevel())
			mainCtrl.loadLevelFromFile();

		// loads a level out of a folder.
		else if (a.getSource() == mainWnd.getMntmSaveLevel())
			mainCtrl.saveLevelToFile();

		// saves the current game.
		else if (a.getSource() == mainWnd.getMntmSaveGame())
			mainCtrl.saveCurrentGameToFile();

		// loads the current game.
		else if (a.getSource() == mainWnd.getMntmLoadGame())
			mainCtrl.loadSavedGame();
		// About angucken
		else if (a.getSource() == mainWnd.getMntmAbout())
			mainWnd.openAbout();

		// Host Network
		else if (a.getSource() == mainWnd.getMnHostGame()) {
			mainWnd.setMainCtrl(new NetworkServerInteraction(bsg, mainWnd));
		}
		// Join Network
		else if (a.getSource() == mainWnd.getMnJoinGame()) {
			IODialog dia = new IODialog();
			String ip = dia.readLine("IP-Addresse:");
			mainWnd.setMainCtrl(new NetworkClientInteraction(bsg, mainWnd, ip));
		}

		// Restore Local Game
		else if (a.getSource() == mainWnd.getMntmRestoreLocalGame()) {
			mainWnd.setMainCtrl(new UserInteraction(bsg, mainWnd));
		}

		// english
		else if (a.getSource() == mainWnd.getRdbtnmntmLangEn()) {
			mainWnd.setLocale(Locale.US);
			mainWnd.resetJMenu();
			if (mainCtrl.getHighScoreFrame() != null)
				mainCtrl.getHighScoreFrame().updateLabels();
		}

		// german
		else if (a.getSource() == mainWnd.getRdbtnmntmLangDe()) {
			mainWnd.setLocale(Locale.GERMANY);
			mainWnd.resetJMenu();
			if (mainCtrl.getHighScoreFrame() != null)
				mainCtrl.getHighScoreFrame().updateLabels();
		}

		// loads the default skin.
		else if (a.getSource() == mainWnd.getRdbtnmntmSkinDefault()) {
			mainWnd.getGamePanel()
					.loadSkin(
							new Skin(
									new File(
											"src/de/tu_darmstadt/gdi1/resources/images/defaultskin")));
			try {
				mainWnd.getGamePanel().redraw();
			} catch (InternalFailureException e) {
				return;
			}
		}
		// loads the most wonderful skins of ALL!!!!!!!111
		else if (a.getSource() == mainWnd.getRdbtnmntmSkinUgly()) {
			mainWnd.getGamePanel().loadSkin(
					new Skin(new File(
							"src/de/tu_darmstadt/gdi1/resources/images/ugly")));
			try {
				mainWnd.getGamePanel().redraw();
			} catch (InternalFailureException e) {
				return;
			}
		}
		// loads the terminal skin
		else if (a.getSource() == mainWnd.getRdbtnmntmSkinTerminal()) {
			mainWnd.getGamePanel()
					.loadSkin(
							new Skin(
									new File(
											"src/de/tu_darmstadt/gdi1/resources/images/terminal")));
			try {
				mainWnd.getGamePanel().redraw();
			} catch (InternalFailureException e) {
				return;
			}
		}
		// loads the fish skin.
		else if (a.getSource() == mainWnd.getRdbtnmntmSkinFische()) {
			mainWnd.getGamePanel()
					.loadSkin(
							new Skin(
									new File(
											"src/de/tu_darmstadt/gdi1/resources/images/fische")));
			try {
				mainWnd.getGamePanel().redraw();
			} catch (InternalFailureException e) {
				return;
			}
		}
		// exits program.
		else if (a.getSource() == mainWnd.getMntmExit())
			mainCtrl.exitProgramm();

		// Changes Player Name in StatusPanel
		else if (a.getSource() == mainWnd.getStatusPanel().getTxtPlayer())
			bsg.setPlayerName(mainWnd.getStatusPanel().getTxtPlayer().getText());

		// Changes GameMode
		else if (a.getSource() == mainWnd.getStatusPanel()
				.getChckbxShootsPerPart()) {

			boolean selected = mainWnd.getStatusPanel()
					.getChckbxShootsPerPart().isSelected();
			int number = mainWnd.getStatusPanel().getSlider().getValue();
			// User confirmation
			if (JOptionPane.showConfirmDialog(mainWnd,
					"Level will be reloaded. Continue?") == JOptionPane.YES_OPTION) {
				// (De) Activate Ammo-Mode
				bsg.setAmmunitionMode(selected);
				bsg.setAmmunitionNumber(number);

				// Update View
				mainWnd.getStatusPanel().getSlider().setEnabled(selected);
				try {
					bsg.restartLevel();
				} catch (InvalidLevelFileException e) {
					mainWnd.showMessage("Error while reloading Level");
				}
				try {
					mainWnd.notifyLevelLoaded(21, 10);
				} catch (ParameterOutOfRangeException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (InternalFailureException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}

			// set Checkbox/Slider state
			mainWnd.getStatusPanel().getChckbxShootsPerPart()
					.setSelected(bsg.isAmmunitionMode());
			mainWnd.getStatusPanel().getSlider()
					.setValue(bsg.getAmmunitionNumber());
		}

	}

	/**
	 * Implements the method which detects the keys pressed and performs the
	 * appropriate action.
	 */
	public void keyPressed(KeyEvent key) {

		// retrieve the key code and call the appropriate method, if any
		switch (key.getKeyCode()) {
		case KeyEvent.VK_LEFT:

			break;

		case KeyEvent.VK_RIGHT:

			break;

		case KeyEvent.VK_UP:

			break;

		case KeyEvent.VK_DOWN:

			break;

		case KeyEvent.VK_Q:

			break;

		case KeyEvent.VK_N:
			mainCtrl.userPressedN();
			break;

		case KeyEvent.VK_BACK_SPACE:

			break;

		case KeyEvent.VK_ENTER:

			break;

		case KeyEvent.VK_SPACE:

			break;

		case KeyEvent.VK_V:
			mainCtrl.userPressedV();
			break;

		default:
			// keyOtherPressed(key);
			break;
		}

	}

	@Override
	/**
	 * Method from the keyListener's interface, that detects whenever a key is released.
	 */
	public void keyReleased(KeyEvent arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	/**
	 * Method from the keyListener's Interface that detects whenever a key is typed on the keyboard 
	 */
	public void keyTyped(KeyEvent arg0) {
		// TODO Auto-generated method stub

	}

}
